<style lang="less">
@import './roleManage.less';
</style>
<template>
  <div class="search">
    <Row>
      <Col>
      <Card>
        <Row class="operation">
          <Button @click="addRole"
                  type="primary"
                  icon="md-add">添加角色</Button>
          <!-- <Button @click="delAll" icon="md-trash">批量删除</Button>
            <Button @click="init" icon="md-refresh">刷新</Button> -->
        </Row>
        <!-- <Row>
          <Alert show-icon>
            已选择
            <span class="select-count">{{selectCount}}</span> 项
            <a class="select-clear"
               @click="clearSelectAll">清空</a>
          </Alert>
        </Row> -->
        <Row>
          <Table :loading="loading"
                 max-height="600"
                 border
                 :columns="columns"
                 :data="data"
                 ref="table"
                 sortable="custom"
                 @on-sort-change="changeSort"
                 @on-selection-change="changeSelect"></Table>
        </Row>
        <Row type="flex"
             justify="end"
             class="page">
          <Page :current="pageNumber"
                :total="total"
                :page-size="pageSize"
                @on-change="changePage"
                @on-page-size-change="changePageSize"
                :page-size-opts="[10,20,50,100]"
                size="small"
                show-total
                show-elevator
                show-sizer></Page>
        </Row>
      </Card>
      </Col>
    </Row>
    <!-- 编辑 -->
    <Modal :title="modalTitle"
           v-model="roleModalVisible"
           :mask-closable="false"
           :width="500">
      <Form ref="roleForm"
            :model="roleForm"
            :label-width="80"
            :rules="roleFormValidate"
            style="padding-right:30px">
        <FormItem label="角色名称"
                  prop="roleName">
          <Input v-model="roleForm.roleName" />
        </FormItem>
        <FormItem label="备注"
                  prop="remark">
          <Input v-model="roleForm.remark" />
        </FormItem>
      </Form>
      <div slot="footer">
        <Button type="text"
                @click="cancelRole">取消</Button>
        <Button type="primary"
                :loading="submitLoading"
                @click="submitRole">提交</Button>
      </div>
    </Modal>
    <!-- 菜单权限 -->
    <Modal :title="modalTitle"
           v-model="permModalVisible"
           :mask-closable="false"
           :width="500"
           :styles="{top: '30px'}"
           class="permModal">
      <Tree ref="tree"
            :data="permData"
            multiple
            show-checkbox
            :render="renderContent"
            :check-strictly="false"></Tree>
      <Spin size="large"
            fix
            v-if="treeLoading"></Spin>
      <div slot="footer">
        <Button type="text"
                @click="cancelPermEdit">取消</Button>
        <Select v-model="openLevel"
                @on-change="changeOpen"
                style="width:100px;text-align:left;margin-right:10px">
          <Option value="0">展开所有</Option>
          <Option value="1">收合所有</Option>
          <Option value="2">仅展开一级</Option>
          <Option value="3">仅展开两级</Option>
        </Select>
        <Button @click="selectTreeAll">全选/反选</Button>
        <Button type="primary"
                :loading="submitPermLoading"
                @click="submitPermEdit">提交</Button>
      </div>
    </Modal>
    <!-- 数据权限 -->
    <Modal :title="modalTitle"
           v-model="depModalVisible"
           :mask-closable="false"
           :width="500"
           :styles="{top: '30px'}"
           class="depModal">
      <Form :label-width="65">
        <FormItem label="数据范围">
          <Select v-model="dataType">
            <Option :value="0">全部数据权限</Option>
            <Option :value="1">自定义数据权限</Option>
          </Select>
        </FormItem>
      </Form>
      <Alert show-icon>默认可查看全部数据，自定义数据范围请点击选择下方数据</Alert>
      <div v-if="dataType!=0"
           style="margin-top:15px">
        <Tree ref="depTree"
              :data="depData"
              :load-data="loadData"
              @on-toggle-expand="expandCheckDep"
              multiple
              style="margin-top:15px"></Tree>
        <Spin size="large"
              v-if="depTreeLoading"></Spin>
      </div>
      <div slot="footer">
        <Button type="text"
                @click="depModalVisible=false">取消</Button>
        <Button type="primary"
                :loading="submitDepLoading"
                @click="submitDepEdit">提交</Button>
      </div>
    </Modal>
  </div>
</template>

<script>
import {
  getRolePageList,
  getRoleInfo,
  getAllMenuList,
  getAllPermissionList,
  addRole,
  editRole,
  deleteRole,
  editRolePerm,
  initDepartment,
  loadDepartment,
  editRoleDep
} from '@/api/index'
import util from '@/libs/util.js'
export default {
  name: 'role-manage',
  data() {
    return {
      openLevel: '0',
      loading: true,
      treeLoading: true,
      depTreeLoading: true,
      submitPermLoading: false,
      submitDepLoading: false,
      searchKey: '',
      sortColumn: 'createTime',
      sortType: 'desc',
      modalType: 0,
      roleModalVisible: false,
      permModalVisible: false,
      depModalVisible: false,
      modalTitle: '',
      roleForm: {
        roleName: '',
        remark: ''
      },
      roleFormValidate: {
        roleName: [
          { required: true, message: '角色名称不能为空', trigger: 'blur' }
        ]
      },
      submitLoading: false,
      selectList: [],
      selectCount: 0,
      columns: [
        // {
        //   type: 'selection',
        //   width: 60,
        //   align: 'center'
        // },
        {
          title: '序号',
          type: 'index',
          width: 65,
          align: 'center',
          fixed: 'left'
        },
        {
          title: '角色名称',
          key: 'roleName',
          width: 200,
          sortable: true
        },
        {
          title: '备注',
          key: 'remark',
          minWidth: 190
        },
        {
          title: '创建时间',
          key: 'createTime',
          width: 200,
          sortable: true,
          sortType: 'desc'
        },
        {
          title: '操作',
          key: 'action',
          align: 'center',
          fixed: 'right',
          width: 320,
          render: (h, params) => {
            return h('div', [
              h(
                'Button',
                {
                  props: {
                    type: 'warning',
                    size: 'small'
                  },
                  style: {
                    marginRight: '5px'
                  },
                  on: {
                    click: () => {
                      this.editPerm(params.row)
                    }
                  }
                },
                '菜单权限'
              ),
              h(
                'Button',
                {
                  props: {
                    type: 'primary',
                    size: 'small'
                  },
                  style: {
                    marginRight: '5px'
                  },
                  on: {
                    click: () => {
                      this.editDep(params.row)
                    }
                  }
                },
                '数据权限'
              ),
              h(
                'Button',
                {
                  props: {
                    size: 'small'
                  },
                  style: {
                    marginRight: '5px'
                  },
                  on: {
                    click: () => {
                      this.edit(params.row)
                    }
                  }
                },
                '编辑'
              ),
              h(
                'Button',
                {
                  props: {
                    type: 'error',
                    size: 'small'
                  },
                  on: {
                    click: () => {
                      this.remove(params.row)
                    }
                  }
                },
                '删除'
              )
            ])
          }
        }
      ],
      data: [],
      pageNumber: 1,
      pageSize: 10,
      total: 0,
      permData: [],
      permRawData: [],
      editRolePermId: '',
      selectAllFlag: false,
      depData: [],
      dataType: 0,
      editDepartments: []
    }
  },
  methods: {
    init() {
      this.getRolePageList()
      // 获取所有菜单权限树
      this.getPermList()
    },
    renderContent(h, { root, node, data }) {
      let icon = ''
      if (data.level == 0) {
        icon = 'ios-navigate'
      } else if (data.level == 1) {
        icon = 'md-list-box'
      } else if (data.level == 2) {
        icon = 'md-list'
      } else if (data.level == 3) {
        icon = 'md-radio-button-on'
      } else {
        icon = 'md-radio-button-off'
      }
      return h(
        'span',
        {
          style: {
            display: 'inline-block',
            cursor: 'pointer'
          },
          on: {
            click: () => {
              data.checked = !data.checked
            }
          }
        },
        [
          h('span', [
            h('Icon', {
              props: {
                type: icon,
                size: '16'
              },
              style: {
                'margin-right': '8px',
                'margin-bottom': '3px'
              }
            }),
            h('span', { class: 'ivu-tree-title' }, data.title)
          ])
        ]
      )
    },
    changePage(v) {
      this.pageNumber = v
      this.getRolePageList()
      this.clearSelectAll()
    },
    changePageSize(v) {
      this.pageSize = v
      this.getRolePageList()
    },
    changeSort(e) {
      this.sortColumn = e.key
      this.sortType = e.order
      if (e.order == 'normal') {
        this.sortType = ''
      }
      this.getRolePageList()
    },
    getRolePageList() {
      this.loading = true
      let params = {
        current: this.pageNumber,
        size: this.pageSize,
        sort: this.sortColumn,
        order: this.sort
      }
      getRolePageList(params).then(res => {
        this.loading = false
        if (res.code == 0) {
          this.data = res.data.records
          this.total = res.data.total
        }
      })
    },
    getPermList() {
      this.treeLoading = true
      getAllMenuList().then(res => {
        this.treeLoading = false

        if (res.code == 0) {
          this.permRawData = res.data
          if (this.openLevel == '0') {
            this.permRawData.forEach(e => {
              e.expand = true
              if (e.children && e.children.length > 0) {
                e.children.forEach(c => {
                  c.expand = true
                  if (c.children && c.children.length > 0) {
                    c.children.forEach(function(b) {
                      b.expand = true
                    })
                  }
                })
              }
            })
          } else if (this.openLevel == '1') {
            this.permRawData.forEach(e => {
              e.expand = false
              if (e.children && e.children.length > 0) {
                e.children.forEach(c => {
                  c.expand = false
                  if (c.children && c.children.length > 0) {
                    c.children.forEach(function(b) {
                      b.expand = false
                    })
                  }
                })
              }
            })
          } else if (this.openLevel == '2') {
            this.permRawData.forEach(e => {
              e.expand = true
              if (e.children && e.children.length > 0) {
                e.children.forEach(c => {
                  c.expand = false
                  if (c.children && c.children.length > 0) {
                    c.children.forEach(function(b) {
                      b.expand = false
                    })
                  }
                })
              }
            })
          } else if (this.openLevel == '3') {
            this.permRawData.forEach(e => {
              e.expand = true
              if (e.children && e.children.length > 0) {
                e.children.forEach(c => {
                  c.expand = true
                  if (c.children && c.children.length > 0) {
                    c.children.forEach(function(b) {
                      b.expand = false
                    })
                  }
                })
              }
            })
          }
        }
      })
    },
    cancelRole() {
      this.roleModalVisible = false
    },
    submitRole() {
      this.$refs.roleForm.validate(valid => {
        if (valid) {
          if (this.modalType == 0) {
            // 添加
            this.submitLoading = true
            addRole(this.roleForm).then(res => {
              this.submitLoading = false
              if (res.code == 0) {
                this.$Message.success('操作成功')
                this.getRolePageList()
                this.roleModalVisible = false
              }
            })
          } else {
            this.submitLoading = true
            editRole(this.roleForm).then(res => {
              this.submitLoading = false
              if (res.success) {
                this.$Message.success('操作成功')
                this.getRolePageList()
                this.roleModalVisible = false
              }
            })
          }
        }
      })
    },
    addRole() {
      this.modalType = 0
      this.modalTitle = '添加角色'
      this.roleForm = {
        roleName: '',
        remark: ''
      }
      this.roleModalVisible = true
    },
    edit(v) {
      this.modalType = 1
      this.modalTitle = '编辑角色'
      this.$refs.roleForm.resetFields()
      // 转换null为""
      for (let attr in v) {
        if (v[attr] == null) {
          v[attr] = ''
        }
      }
      let str = JSON.stringify(v)
      let roleInfo = JSON.parse(str)
      this.roleForm = roleInfo
      this.roleModalVisible = true
    },
    remove(v) {
      this.$Modal.confirm({
        title: '确认删除',
        content: '您确认要删除角色 ' + v.roleName + ' ?',
        loading: true,
        onOk: () => {
          deleteRole(v.roleId).then(res => {
            this.$Modal.remove()
            if (res.code == 0) {
              this.$Message.success('删除成功')
              this.getRolePageList()
            }
          })
        }
      })
    },
    clearSelectAll() {
      this.$refs.table.selectAll(false)
    },
    changeSelect(e) {
      this.selectList = e
      this.selectCount = e.length
    },
    delAll() {
      if (this.selectCount <= 0) {
        this.$Message.warning('您还未选择要删除的数据')
        return
      }
      this.$Modal.confirm({
        title: '确认删除',
        content: '您确认要删除所选的 ' + this.selectCount + ' 条数据?',
        loading: true,
        onOk: () => {
          let ids = ''
          this.selectList.forEach(function(e) {
            ids += e.id + ','
          })
          ids = ids.substring(0, ids.length - 1)
          deleteRole(ids).then(res => {
            this.$Modal.remove()
            if (res.success) {
              this.$Message.success('删除成功')
              this.clearSelectAll()
              this.getRolePageList()
            }
          })
        }
      })
    },
    editPerm(v) {
      let me = this
      this.treeLoading = true
      this.permModalVisible = true
      this.openLevel = '0'
      this.modalTitle = '分配 ' + v.roleName + ' 的菜单权限'
      getRoleInfo(v.roleId).then(res => {
        if (res.code == 0) {
          setTimeout(function() {
            me.permData = JSON.parse(JSON.stringify(me.permRawData))
            // 匹配勾选
            me.editRolePermId = v.roleId
            let rolePerms = res.data.menuIdList
            // 递归判断子节点
            me.checkPermTree(me.permData, rolePerms)
            me.treeLoading = false
          }, 1000)
        } else {
          me.treeLoading = false
        }
      })
    },
    // 递归判断子节点
    checkPermTree(permData, rolePerms) {
      let that = this
      permData.forEach(function(p) {
        if (p.children && p.children.length > 0) {
          that.checkPermTree(p.children, rolePerms)
        } else {
          if (that.hasPerm(p, rolePerms)) {
            p.checked = true
          }
        }
      })
    },
    // 判断角色拥有的权限节点勾选
    hasPerm(p, rolePerms) {
      let flag = false
      for (let i = 0; i < rolePerms.length; i++) {
        if (p.menuId == rolePerms[i]) {
          flag = true
          break
        }
      }
      if (flag) {
        return true
      }
      return false
    },
    // 全选反选
    selectTreeAll() {
      this.selectAllFlag = !this.selectAllFlag
      let select = this.selectAllFlag
      this.selectedTreeAll(this.permData, select)
    },
    // 递归全选节点
    selectedTreeAll(permData, select) {
      let that = this
      permData.forEach(function(e) {
        e.checked = select
        if (e.children && e.children.length > 0) {
          that.selectedTreeAll(e.children, select)
        }
      })
    },
    submitPermEdit() {
      this.submitPermLoading = true
      let permIds = this.$refs.tree
        .getCheckedAndIndeterminateNodes()
        .map(val => val.menuId)
      editRolePerm({
        roleId: this.editRolePermId,
        menuIdList: permIds
      }).then(res => {
        this.submitPermLoading = false
        if (res.code == 0) {
          this.$Message.success('操作成功')
          // 标记重新获取菜单数据
          this.$store.commit('setAdded', false)
          util.initRouter(this)
          this.getRolePageList()
          this.permModalVisible = false
        }
      })
    },
    cancelPermEdit() {
      this.permModalVisible = false
    },
    loadData(item, callback) {
      loadDepartment(item.id, { openDataFilter: false }).then(res => {
        if (res.success) {
          res.result.forEach(function(e) {
            e.selected = false
            if (e.isParent) {
              e.loading = false
              e.children = []
            }
            if (e.status == -1) {
              e.title = '[已禁用] ' + e.title
              e.disabled = true
            }
          })
          callback(res.result)
        }
      })
    },
    editDep(v) {
      this.dataType = 0
      this.editRolePermId = v.id
      this.modalTitle = '分配 ' + v.name + ' 的数据权限'
      if (v.dataType) {
        this.dataType = v.dataType
      }
      // 匹配勾选
      let roleDepIds = v.departments
      this.editDepartments = roleDepIds
      this.depTreeLoading = true
      initDepartment({ openDataFilter: false }).then(res => {
        this.depTreeLoading = false
        if (res.success) {
          res.result.forEach(function(e) {
            e.selected = false
            if (e.isParent) {
              e.loading = false
              e.children = []
            }
            if (e.status == -1) {
              e.title = '[已禁用] ' + e.title
              e.disabled = true
            }
          })
          this.depData = res.result
          // 判断子节点
          this.checkDepTree(this.depData, roleDepIds)
          this.depModalVisible = true
        }
      })
    },
    expandCheckDep(v) {
      // 判断展开子节点
      this.checkDepTree(v.children, this.editDepartments)
    },
    // 判断子节点
    checkDepTree(depData, roleDepIds) {
      let that = this
      depData.forEach(function(p) {
        if (that.hasDepPerm(p, roleDepIds)) {
          p.selected = true
        } else {
          p.selected = false
        }
      })
    },
    // 判断角色拥有的权限节点勾选
    hasDepPerm(p, roleDepIds) {
      let flag = false
      for (let i = 0; i < roleDepIds.length; i++) {
        if (p.id == roleDepIds[i].departmentId) {
          flag = true
          break
        }
      }
      if (flag) {
        return true
      }
      return false
    },
    submitDepEdit() {
      let depIds = ''
      if (this.dataType != 0) {
        let selectedNodes = this.$refs.depTree.getSelectedNodes()
        if (selectedNodes.length < 1) {
          this.$Message.error('请至少选择一条数据')
          return
        }
        selectedNodes.forEach(function(e) {
          depIds += e.id + ','
        })
        depIds = depIds.substring(0, depIds.length - 1)
      }
      this.submitDepLoading = true
      editRoleDep({
        roleId: this.editRolePermId,
        dataType: this.dataType,
        depIds: depIds
      }).then(res => {
        this.submitDepLoading = false
        if (res.success) {
          this.$Message.success('操作成功')
          this.getRolePageList()
          this.depModalVisible = false
        }
      })
    },
    changeOpen(v) {
      if (v == '0') {
        this.permData.forEach(e => {
          e.expand = true
          if (e.children && e.children.length > 0) {
            e.children.forEach(c => {
              c.expand = true
              if (c.children && c.children.length > 0) {
                c.children.forEach(function(b) {
                  b.expand = true
                })
              }
            })
          }
        })
      } else if (v == '1') {
        this.permData.forEach(e => {
          e.expand = false
          if (e.children && e.children.length > 0) {
            e.children.forEach(c => {
              c.expand = false
              if (c.children && c.children.length > 0) {
                c.children.forEach(function(b) {
                  b.expand = false
                })
              }
            })
          }
        })
      } else if (v == '2') {
        this.permData.forEach(e => {
          e.expand = true
          if (e.children && e.children.length > 0) {
            e.children.forEach(c => {
              c.expand = false
              if (c.children && c.children.length > 0) {
                c.children.forEach(function(b) {
                  b.expand = false
                })
              }
            })
          }
        })
      } else if (v == '3') {
        this.permData.forEach(e => {
          e.expand = true
          if (e.children && e.children.length > 0) {
            e.children.forEach(c => {
              c.expand = true
              if (c.children && c.children.length > 0) {
                c.children.forEach(function(b) {
                  b.expand = false
                })
              }
            })
          }
        })
      }
    }
  },
  mounted() {
    this.init()
  }
}
</script>